library Beams initializer init requires T32n, PhysicsPsuedoNatives

    globals
        //private string ID = "TCLE"
        //private string ID = "TCL2"
        private string ID = "TCLE"
        //private string ID = "HWPB"
        
        private integer N = -1
        private integer MAX = 30
        private BeamHelper array L
    endglobals
    
    private function NewBeam takes nothing returns BeamHelper
        if(N> MAX) then
            return BeamHelper.create()
        endif
        set N = N + 1
        return L[N]
    endfunction
    
    private function RecycleBeam takes BeamHelper l returns nothing
        if(N < 0) then
            call l.destroy()
            return
        endif
        set L[N] = l   
        set N = N - 1
       
        call MoveLightningEx(l.l,false,0,0,0,0,0,0)
        
        set l.x1 = 0
        set l.x2 = 0
        set l.y1 = 0
        set l.y2 = 0
        set l.z1 = 0
        set l.z2 = 0
        
        set l.dx1 = 0
        set l.dy1 = 0
        set l.dz1 = 0
        set l.dx2 = 0
        set l.dy2 = 0
        set l.dz2 = 0
        
        set l.r = 0
        set l.g = 0
        set l.b = 0
        set l.a = 0
        
        set l.dr = 0
        set l.dg = 0
        set l.db = 0
        set l.da = 0
        
    endfunction
    
    
   struct BeamHelper
    
        real x1=0
        real x2=0
        real y1=0
        real y2=0
        real z1=0
        real z2=0
        
        real dx1=0
        real dx2=0
        real dy1=0
        real dy2=0
        real dz1=0
        real dz2=0
        
        real r=0
        real g=0
        real b=0
        real a=0
        
        real dr=0
        real dg=0
        real db=0
        real da=0

        lightning l = null
        
        real t = 0
        real dt = 0
        boolean v = false
        
        method onDestroy takes nothing returns nothing
            call DestroyLightning(.l)
            set .l = null
        endmethod
        
        method tick takes nothing returns nothing
        
            set .t = .t - .dt
            if(.t <= 0) then
                call .stop()
                call RecycleBeam(this)
            endif
            
            set .r = .r + .dr
            set .g = .g + .dg
            set .b = .b + .db
            set .a = .a + .da
            set .x1 = .x1 + .dx1
            set .y1 = .y1 + .dy1
            set .z1 = .z1 + .dz1
            set .x2 = .x2 + .dx2
            set .y2 = .y2 + .dy2
            set .z2 = .z2 + .dz2
            
            if(.r > 255) then
                set .r = 255
                set .dr = 0
            endif
            
            if(.g>255) then
                set .g = 255
                set .dg = 0
            endif
            
            if(.b>255) then
                set .b = 255
                set .db = 0
            endif
            
            if(.a>255) then
                set .a = 255
                set .da = 0
            endif
            
            call SetLightningColor(.l,.r,.g,.b,.a)
            call MoveLightningEx(.l,.v,.x1,.y1,.z1,.x2,.y2,.z2)
        endmethod
        implement T32n
        
        method startBeam takes nothing returns nothing
            call .start()
            set .dt = GetGameTick()
            call SetLightningColor(.l,.r,.g,.b,.a)
            call MoveLightningEx(.l,.v,.x1,.y1,.z1,.x2,.y2,.z2)
        endmethod
        
        static method create takes nothing returns thistype
            local thistype X = .allocate()
            set X.l = AddLightning(ID,false,0,0,0,0)
            return X
        endmethod
        
    endstruct
    
 
    function BlueLaser takes real sx, real sy, real sz, real x, real y, real z returns nothing
        local BeamHelper l = NewBeam()

        set l.x1 = sx
        set l.x2 = x
        set l.y1 = sy
        set l.y2 = y
        set l.z1 = sz
        set l.z2 = z
        
        set l.r = 10
        set l.g = 10
        set l.b = 0
        set l.a = 0
        
        set l.dr = 15
        set l.dg = 15
        set l.db = 7
        set l.da = 7
        
        set l.t = 1.0
        
        call l.startBeam()
    endfunction
    
    
    
    globals
        private real SX = 0
        private real SY = 0
        private real SZ = 0
        private real DX = 0
        private real DY = 0
        private real DZ = 0
    endglobals

    private function ShotgunBeamsHelper takes nothing returns nothing
    
        local real dist = DistanceBetweenPoints2(SX,SY,DX,DY)
        
        local real sx = SX
        local real sy = SY
        local real sz = SZ
        
        local real dx = DX + GetRandomReal(-30, 30 ) + GetRandomReal(dist/-7, dist/7)
        local real dy = DY + GetRandomReal(-30, 30 ) + GetRandomReal(dist/-7, dist/7)
        local real dz = DZ + GetRandomReal(0,10)
         
        local real zplanex = dist 
        
        local real ang1 = AngleBetweenPointsRad(sx,sy,dx,dy)
        local real ang2 = AngleBetweenPointsRad(sx,sz,zplanex,dz)
        
        local real cosXY = Cos(ang1)
        local real sinXY = Sin(ang1)
        local real cosXZ = Cos(ang2)
        local real sinXZ = Sin(ang2)
        
        local BeamHelper l = NewBeam()
        
        local real dd1 = GetRandomReal(16,64)
        local real dd2 = GetRandomReal(64,256)
        
        set l.x1 = sx + dd1 * cosXY
        set l.y1 = sy + dd1 * sinXY
        set l.z1 = sz + 15 
        
        set l.x2 = sx + dd2 * cosXY
        set l.y2 = sy + dd2 * sinXY
        set l.z2 = dz 

        set l.dx1 = 100 * cosXY
        set l.dy1 = 100 * sinXY
        set l.dz1 = 50 * sinXZ
         
        set l.dx2 = 100 * cosXY
        set l.dy2 = 100 * sinXY
        set l.dz2 = 50 * sinXZ
            
        set l.r = 190
        set l.g = 190
        set l.b = 240
        set l.a = 170
            
        set l.dr = 7
        set l.dg = 7
        set l.db = 10
        set l.da = 6

        set l.t = 0.11 * dist/250
        if(l.t < 0.11) then
            set l.t = 0.11
        endif
        call l.startBeam()
    endfunction
    
    private function ShotgunBeamsHelper2 takes nothing returns nothing
    
        local real sx = SX
        local real sy = SY
        local real sz = SZ
        local real dx = DX 
        local real dy = DY 
        local real dz = DZ 
        
        local real zplanex = (dx - sx)*(dx - sx) + (dy - sy) * (dy - sy)
        local real ang1 = AngleBetweenPointsRad(sx,sy,dx,dy)
        local real ang2 = AngleBetweenPointsRad(sx,sz,zplanex,dz)
        local real cosXY = Cos(ang1)
        local real sinXY = Sin(ang1)
        local real cosXZ = Cos(ang2)
        local real sinXZ = Sin(ang2)
        
        local BeamHelper l = NewBeam()
            
        set l.x1 = sx + 32 * cosXY
        set l.y1 = sy + 32 * sinXY
        set l.z1 = sz + 15 
        
        set l.x2 = dx - 90 + GetRandomReal(5.0,200.0)
        set l.y2 = dy - 90 + GetRandomReal(5.0,200.0)
        set l.z2 = dz - 20 + GetRandomReal(5.0,50.0)

        set l.dx1 = 4 * cosXY
        set l.dy1 = 4 * sinXY
        set l.dz1 = 3 * sinXZ
         
        set l.dx2 = 60 * cosXY
        set l.dy2 = 60 * sinXY
        set l.dz2 = 3 * sinXZ
            
        set l.r = 190
        set l.g = 190
        set l.b = 240
        set l.a = 170
            
        set l.dr = 7
        set l.dg = 7
        set l.db = 10
        set l.da = 6
            
        set l.t = 0.1
        call l.startBeam()
    endfunction
    
    function ShotgunBeams takes real x, real y, real z, real x2, real y2, real z2 returns nothing
        local integer i = 0
        loop
            exitwhen i > 10
            set i = i + 1
            set SX = x
            set SY = y 
            set SZ = z 
            set DX = x2
            set DY = y2
            set DZ = z2 
            call ShotgunBeamsHelper()
        endloop
    endfunction
    
    function PistolBeam takes real x, real y, real z, real x2, real y2, real z2 returns nothing
        set SX = x
        set SY = y 
        set SZ = z 
        set DX = x2
        set DY = y2
        set DZ = z2 
        call ShotgunBeamsHelper()
    endfunction
    
    private function init takes nothing returns nothing
        local integer i = 0 
        loop
            exitwhen i> MAX
            set L[i] = BeamHelper.create()
            set i = i + 1
        endloop
    endfunction
    
    function SpawnBeam takes nothing returns nothing
    
    endfunction
	
endlibrary
